package classLoad;

import lombok.SneakyThrows;

/**
 * https://www.bilibili.com/video/BV1vJ41177cw
 * 当我们调用 loadClass 方法加载类时，会采用双亲委派模式，即如果类已经被加载，就从缓存中获取，不会重新加载。
 * 如果同一个 class 被同一个类加载器多次加载，则会报错。
 * 因此，我们要实现热部署让同一个class文件被不同的类加载器重复加载即可。
 * 但是不能调用 loadClass 方法，而应该调用 findClass 方法，避开双亲委托模式，从而实现同一个类被多次加载，实现热部署。
 */
public class HotDeployment {

    public static void main(String[] args) {
        demo1();
        demo2();
    }

    @SneakyThrows
    public static void demo1() {
        CustomizeFileClassLoader classLoader1 = new CustomizeFileClassLoader("d:/"); // 父类加载器：APPClassLoader
        CustomizeFileClassLoader classLoader2 = new CustomizeFileClassLoader(classLoader1, "d:/");
        Class class1 = classLoader1.loadClass("classLoad.Son");
        Class class2 = classLoader2.loadClass("classLoad.Son");
        System.out.println(class1.hashCode());
        System.out.println(class2.hashCode());
        // 结果：class1 和 class2 的 hashCode 一致
    }

    @SneakyThrows
    public static void demo2() {
        CustomizeFileClassLoader classLoader1 = new CustomizeFileClassLoader("d:/"); // 父类加载器：APPClassLoader
        CustomizeFileClassLoader classLoader2 = new CustomizeFileClassLoader(classLoader1, "d:/");
        Class class1 = classLoader1.findClass("classLoad.Son");
        Class class2 = classLoader2.findClass("classLoad.Son");
        System.out.println(class1.hashCode());
        System.out.println(class2.hashCode());
        // 结果：class1 和 class2 的 hashCode 不一致
    }
}
